package models

import (
	"time"
)

//root transaction info
type RootTransaction struct {
	RootXid string
	// 0:trying, 1-confirming, 2-confirmed, 3-cancelling, 4-cancelled
	RootTxnStat             string
	RootTxnRegisterTime     time.Time
	RootTxnStartRecoverTime time.Time // only recover use
	HasExpireTime           bool
	//RootTxnStartTime      time.Time
	//RootTxnLastUpdateTime time.Time
	//RootTxnEndTime time.Time
	Branches []*Transaction
}

//branch transaction info
type Transaction struct {
	RootXid            string
	ParentXid          string
	BranchXid          string
	ParticipantAddress string
	// 0:trying, 1-confirmed, 2-cancelled
	BranchTxnStat      string
	BranchTxnStartTime time.Time
	//BranchTxnEndTime              time.Time
	BranchTxnLastUpdateTime       time.Time
	RecoveryTimes                 int // only recover use
	ServiceName                   string
	ParamData                     string
	TryFailedIgnoreCallbackCancel bool
	ClientSDKVersion              string
	Environment                   string
	Workspace                     string
	Headers                       string
}

func (t *Transaction) IsRoot() bool {
	return t.RootXid == t.BranchXid
}

func (t *Transaction) GetClientSDKVersion() string {
	return t.ClientSDKVersion
}

func (t *Transaction) IsClientSDKVersionInList(versions ...string) bool {
	for _, v := range versions {
		if t.ClientSDKVersion == v {
			return true
		}
	}

	return false
}

func (t *Transaction) IsClientSDKVersion(version string) bool {
	return version == t.ClientSDKVersion
}

func (t *Transaction) IsTheFirstTimeToRecover() bool {
	return t.BranchTxnLastUpdateTime.IsZero()
}

func (t *Transaction) IsRecoverTimeExceededLimit(limitSeconds int64) bool {
	return time.Now().Unix()-t.BranchTxnLastUpdateTime.Unix() < limitSeconds
}

func (t *RootTransaction) IsTheFirstTimeToRecover() bool {
	return t.RootTxnStartRecoverTime.IsZero()
}

func (t *RootTransaction) IsRecoverTimeExceededLimit(limitSeconds int64) bool {
	return time.Now().Unix()-t.RootTxnStartRecoverTime.Unix() > limitSeconds
}
